' view.bmx

Import "nodeview.bmx"

Import MaxGUI.MaxGUI

Strict

Global EventMap:TMap

Function EventHandler:Object(id,data:Object,context:Object)
	Local event:TEvent
	Local target:Object
	Local source:Object
	
	event=TEvent(data)
	If event
		CurrentEvent=event	
'		DebugLog currentevent.ToString()
		source=event.source
		If EventMap And source 
			target=EventMap.ValueForKey(source)
		EndIf
		If CurrentEvent.id=EVENT_GADGETACTION	
'			DebugStop
		EndIf
		If target 
			Return target.SendMessage(data,context)
		EndIf
	EndIf
	Return data
End Function

Function AddEventHandler(src:Object,data:Object)
	If Not EventMap
		EventMap=New TMap
		AddHook EmitEventHook,EventHandler,EventMap
	EndIf
	EventMap.Insert src,data
End Function
	
Type TView Extends TDataNode

	Const VERTICAL_FLOW=1
	Const HORIZONTAL_FLOW=2
	Const LOCKED_FLOW=3
	
	Field	relative,flow
	Field	xpos,ypos,width,height
	Field	clean

	Method New()
		visible=False
	End Method

	Method Reset() 
	End Method
	
	Method OnEvent()
	End Method
	
	Method Dirty(cause:TDataNode)
		Local	node:TDataNode
		node=parent
		While node
			If TView(node) Return TView(node).Dirty(cause)
			node=node.parent
		Wend
	End Method

	Method SetRelative(yesno=True)
		relative=yesno
	End Method		
	
	Method SetVerticalFlow()
		flow=VERTICAL_FLOW
	End Method

	Method SetHorizontalFlow()
		flow=HORIZONTAL_FLOW
	End Method

	Method SetLockedFlow()
		flow=LOCKED_FLOW
	End Method
	
	Method SetPosition(x,y)
		xpos=x
		ypos=y
	End Method		

	Method SetSize(w,h)
		width=w
		height=h
	End Method		
	
	Method Layout()
		Local	penx,peny
		Local	bigx,bigy
		Local	child:TView
		If flow
			If Not relative penx=xpos;peny=ypos
			For child=EachIn kids
				If flow=LOCKED_FLOW
					child.SetSize width,height
					child.Reshape
				Else
					If penx<>child.xpos Or peny<>child.ypos child.SetPosition penx,peny
					child.Layout
					bigx=Max(bigx,child.xpos+child.width)
					bigy=Max(bigy,child.ypos+child.height)
					Select flow
					Case HORIZONTAL_FLOW
						penx:+child.width
					Case VERTICAL_FLOW
						peny:+child.height
					EndSelect			
				EndIf
			Next
			If Not relative bigx:-xpos;bigy:-ypos
			If flow<>LOCKED_FLOW SetSize bigx,bigy
		EndIf
	End Method

	Method Reshape()
		Local	child:TView		
		For child=EachIn kids
			child.Reshape
		Next
	End Method
		
	Method AddPanel:TPanel(name$)
		Return New TPanel.ResetPanel(Self,name)
	End Method

	Method AddCanvas:TCanvas()
		Return New TCanvas.ResetCanvas(Self)
	End Method

	Method AddScrollPanel:TScrollPanel(w,h)
		Return New TScrollPanel.ResetScrollPanel(Self,w,h)
	End Method

	Method AddLabel:TLabel(name$,style=LABEL_LEFT)
		Return New TLabel.CreateLabel(Self,name,style)
	End Method

	Method AddButton:TButton(name$,style)
		Return New TButton.CreateButton(Self,name,style)
	End Method

	Method AddView:TView(name$)
		Local p:TPanel
'		Return Self
		If Not name Return Self
		If TPanel(Self) Return Self
		p=AddPanel("")	'anon means flat link not parent
		p.SetHorizontalFlow()
		New TLabel.CreateLabel(p,name,LABEL_LEFT)
		Return p
	End Method
	
	Method AddColorButton:TColorButton(name$,rgb)
		Return New TColorButton.CreateColorButton(AddView(name),name,rgb)
'		Return New TColorButton.CreateColorButton(Self,name,rgb)
	End Method

	Method AddFontButton:TFontButton(name$,face$,size,style)
		Return New TFontButton.CreateFontButton(AddView(name),name,face,size,style)
'		Return New TFontButton.CreateFontButton(Self,name,face,size,style)
	End Method

	Method AddPathButton:TPathButton(name$,url$)
		Return New TPathButton.CreatePathButton(AddView(name),name,url)
	End Method

	Method AddComboButton:TComboButton(name$,options$[])
		Return New TComboButton.CreateComboButton(AddView(name),name,options)
'		Return New TComboButton.CreateComboButton(Self,name,options)
	End Method

	Method AddNumberButton:TNumberButton(name$,value)
		Return New TNumberButton.CreateNumberButton(AddView(name),name,value)
'		Return New TNumberButton.CreateNumberButton(Self,name,value)
	End Method
End Type

Type TGadgetView Extends TView
	Field gadget:TGadget

	Method New()
		SetRelative True
	End Method

	Method OnEvent()
		DebugLog "TGadgetView:OnEvent received by inactive gadget "+name
	End Method
	
	Method SendMessage:Object( message:Object,sender:Object )
		OnEvent
	End Method

	Method SetGadget(g:TGadget)
		gadget=g
		AddEventHandler g,Self
'		SetGadgetTarget g,Self simon come here !
	End Method

	Method Reshape()
		If gadget gadget.SetShape xpos,ypos,width,height
		Super.Reshape
	End Method
	
	Method ParentGadget:TGadget()
		Local n:TDataNode
		Local g:TGadgetView
		n=parent
		While n
			g=TGadgetView(n)
			If g Return g.gadget
			n=n.parent
		Wend
	End Method
End Type


Type TPanel Extends TGadgetView
	Field namedgroup

	Method SetSize(w,h)
		If namedgroup w:+20;h:+20
		Super.SetSize w,h
	End Method
	
	Method ResetPanel:TPanel(parent:TDataNode,name$="")
		parent.append Self
		SetVerticalFlow
		If name
			namedgroup=True
			SetName name
			
			SetGadget maxgui.maxgui.CreatePanel(xpos,ypos,width,height,ParentGadget(),PANEL_GROUP)

			gadget.SetText name
		Else
			SetGadget maxgui.maxgui.CreatePanel(xpos,ypos,width,height,ParentGadget())
		EndIf
		Return Self
	End Method
End Type			

Type TCanvas Extends TGadgetView
	Method ResetCanvas:TCanvas(parent:TDataNode)
		parent.append Self
		SetLockedFlow
		SetGadget maxgui.maxgui.CreateCanvas(xpos,ypos,width,height,ParentGadget())
		Return Self
	End Method
End Type

Type TLabel Extends TGadgetView

	Method Reshape()
		Local y=ypos+2
		Local h=height-2
?WIN32
		y=y+3
		h=h-3
?
		If gadget gadget.SetShape xpos,y,width,h
		Local	child:TView		
		For child=EachIn kids
			child.Reshape
		Next
	End Method
	
	Method CreateLabel:TLabel(parent:TDataNode,name$,style=LABEL_LEFT)
		Local w=96,h=28		
'		If name=name.tolower() w=32
		SetSize w,h
		parent.append Self
		SetGadget maxgui.maxgui.CreateLabel(name,xpos,ypos,width-8,height,ParentGadget(),style)
		Return Self
	End Method
End Type

Type TButton Extends TGadgetView
	Method OnEvent()
	End Method
	
	Method Selected()
		Return ButtonState(gadget)
	End Method

	Method FromString(value$)
		Set Int(value)
	End Method
	
	Method ToString$()
		Return ButtonState(gadget)
	End Method
	
	Method Set(value)
		SetButtonState gadget,value
	End Method		
	
	Method CreateButton:TButton(parent:TDataNode,name$,style)
		SetName name
		SetSize 192,24
		parent.append Self
		SetGadget maxgui.maxgui.CreateButton(name,xpos,ypos,width,height,ParentGadget(),style)
		Return Self
	End Method
End Type

Type TFontButton Extends TGadgetView
	Field	font:TGuiFont

	Method Refresh()
		gadget.SetText FontName(font)+":"+FontSize(font)
	End Method
		
	Method Request()
		font=RequestFont(font)
		If font
			Refresh
			Dirty Self
		EndIf
	End Method	
	
	Method OnEvent()
		If EventID()=EVENT_GADGETACTION 
			Request()
		EndIf
	End Method
	
	Method Set(face$,size)
		font=LoadGuiFont(face,size)
		Refresh
	End Method

	Method ToString$()
		Return ""+FontName(font)+","+FontSize(font)
	End Method
	
	Method FromString(s$)
		Local	p,name$,size
		p=s.Find(",")+1
		If Not p Return
		name=s[..p-1]
		size=Int(s[p..])
		Set name,size
		Dirty Self
	End Method
	
	Method CreateFontButton:TFontButton(parent:TDataNode,name$,face$,size,style)
		SetName name
		SetSize 192,24
		parent.Append Self
		SetGadget CreateButton("..",xpos,ypos,width,height,ParentGadget(),1)
		set face,size
		Return Self
	End Method
End Type

Type TColorButton Extends TGadgetView
	Field	red,green,blue
		
	Method Set(rgb)
		red=(rgb Shr 16)&255
		green=(rgb Shr 8)&255
		blue=rgb&255
		SetPanelColor gadget,red,green,blue
	End Method

	Method ToString$()
		Return ""+red+","+green+","+blue
	End Method

	Method FromString(s$)
		Local	p,q
		p=s.Find(",")+1
		If Not p Return
		q=s.Find(",",p)+1
		If Not q Return
		red=Int(s[..p-1])
		green=Int(s[p..q-1])
		blue=Int(s[q..])
		SetPanelColor gadget,red,green,blue
		Dirty Self
	End Method

	Method Request()
		If RequestColor(red,green,blue)
			red=RequestedRed()
			green=RequestedGreen()
			blue=RequestedBlue()
			SetPanelColor gadget,red,green,blue
			Dirty Self
			Return True
		EndIf				
	End Method	
	
	Method OnEvent()
		If EventID()=EVENT_MOUSEDOWN 
			Request()
		EndIf
	End Method

	Method CreateColorButton:TColorButton(parent:TDataNode,name$,rgb)
		SetName name
		SetSize 24,24
		parent.Append Self
		SetGadget CreatePanel(xpos,ypos,width,height,ParentGadget(),PANEL_BORDER|PANEL_ACTIVE)
		set rgb
		Return Self
	End Method
End Type

Type TPathButton Extends TGadgetView
	Field	path$
			
	Method Set(url$)
		If url And url<>path
			path=url
			gadget.SetText path
'			gadget.SetText name+":"+path
		EndIf
	End Method

	Method Request()
		Local	url$
		url=RequestDir(name,path)
		If url
			Set url
			Dirty Self
		EndIf
	End Method	
	
	Method OnEvent()
		If EventID()=EVENT_GADGETACTION 
			Request()
		EndIf
	End Method

	Method ToString$()
		Return path
	End Method
	
	Method FromString(s$)
		Set s$
		Dirty Null
	End Method
	
	Method CreatePathButton:TPathButton(parent:TDataNode,name$,url$)
		SetName name
		SetSize 240,24
		parent.Append Self
'		CreateLabel name
		If Not url url="Not Found"
		SetGadget CreateButton("..",xpos,ypos,width,height,ParentGadget(),1)
		Set url
		Return Self
	End Method
End Type

Type TNumberButton Extends TGadgetView
	Field	value
	
	Method ToString$()
		Return ""+value
	End Method

	Method FromString(s$)
		Set Int(s$)
		Dirty Self
	End Method

	Method Set(val)
		value=val
		SetGadgetText gadget,""+val
	End Method

	Method OnEvent()
		Set Int(TextFieldText(gadget))
		Dirty Self
	End Method

	Method CreateNumberButton:TNumberButton(parent:TDataNode,name$,val)
		Local	a$
		SetName name
		SetSize 140,24
		parent.Append Self
		SetGadget CreateTextField(xpos,ypos,width,height,ParentGadget())
		Set val
		Return Self
	End Method
End Type

Type TComboButton Extends TNumberButton
	Method Set(val)
		value=val
		SelectGadgetItem gadget,val
	End Method

	Method OnEvent()
		Set SelectedGadgetItem(gadget)
		Dirty Self
	End Method
	
	Method FromString(s$)
		SelectGadgetItem gadget,Int(s)
		Dirty Self
	End Method
	
	Method CreateComboButton:TComboButton(parent:TDataNode,name$,options$[])
		Local	a$
		SetName name
		SetSize 140,24
		parent.Append Self
		SetGadget CreateComboBox(xpos,ypos,width,height,ParentGadget())
		For a$=EachIn options
			AddGadgetItem gadget,a$
		Next
'		Set 0
		Return Self
	End Method
End Type


Type TStringButton Extends TGadgetView
	Field	value$
	
	Method ToString$()
		Return value
	End Method

	Method FromString(s$)
		Set s$
		Dirty Self
	End Method

	Method Set(val$)
		value=val
		SetGadgetText gadget,val
	End Method

	Method OnEvent()
		Set TextFieldText(gadget)
		Dirty Self
	End Method

	Method CreateStringButton:TStringButton(parent:TDataNode,name$,val$)
		Local	a$
		SetName name
		SetSize 140,24
		parent.Append Self
		SetGadget CreateTextField(xpos,ypos,width,height,ParentGadget())
		Set val
		Return Self
	End Method
End Type


Type THistoryButton Extends TGadgetView
	Field value$
	Field history:TList
	
	Method ToString$()
		Local s$,h$
		s=value
		For h=EachIn history
			s:+";"+h
		Next
		Return s
	End Method

	Method FromString(s$)
		Local p
		history.Clear()
		While True
			p=s.findlast(";")
			If p=-1 Exit
			history.addlast s[p+1..]
			s=s[..p]
		Wend
		Set s$
		Dirty Self
	End Method

	Method Set(val$)
		value=val
		SetGadgetText gadget,val
	End Method

	Method OnEvent()
		Set TextFieldText(gadget)
		Dirty Self
	End Method

	Method CreateHistoryButton:THistoryButton(parent:TDataNode,name$,val$)
		Local	a$
		SetName name
		SetSize 140,24
		parent.Append Self
		SetGadget CreateComboBox(xpos,ypos,width,height,ParentGadget(),COMBOBOX_EDITABLE)
		Set val
		Return Self
	End Method
End Type


Type TScrollPanel Extends TGadgetView
	Field container:TGadget
	Field scrollbar:TGadget
	Field client:TGadget
	Field cwidth,cheight,ctop

	Method Reshape()
		gadget=Null
		Super.Reshape
		container.SetShape xpos,ypos,width,height
		gadget=client
	End Method

	Method SetSize(w,h)
		cwidth=w+8
		cheight=h+8
		client.setshape(4,4,cwidth,cheight)
		Local ch=ClientHeight(container)
		If cheight<ch cheight=ch
		SetSliderRange scrollbar,ch,cheight
	End Method

	Method OnEvent()
		If EventID()=EVENT_GADGETACTION 
			If EventSource()=scrollbar
				Local sy=SliderValue(scrollbar)
				client.SetShape 4,4-sy,cwidth,cheight
			EndIf
		EndIf
	End Method
	
	Method ResetScrollPanel:TScrollPanel(parent:TDataNode,w,h)
		parent.append Self
		SetVerticalFlow
		Super.SetSize w,h
		container=CreatePanel(xpos,ypos,width,height,ParentGadget())',PANEL_BORDER)
'		SetGadgetColor container,180,180,180
		Local cw,ch
		cw=ClientWidth(container)
		ch=ClientHeight(container)
		scrollbar=CreateSlider(cw-18,0,18,ch,container)
		client=CreatePanel(4,4,cw-18,ch,container)
		SetGadget client		
		AddEventHandler scrollbar,Self
		Return Self
	End Method
End Type

